package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	var path string
	fmt.Println("请输入目录全路径:")
	fmt.Scanf("%s\n", &path)
	fmt.Println("请输入文件类型(后缀名java|go|c):")
	var tp string
	fmt.Scanf("%s\n", &tp)
	files, err := GetFiles(path, tp)
	if err != nil {
		fmt.Println(err)
	}

	var nums int
	for _, file := range files {
		num, _ := GetFileLineNum(file)
		nums += num
	}
	fmt.Println("行数:", nums)
}
func GetFiles(path, tp string) (files []string, err error) {
	var dirs []string
	dir, err := ioutil.ReadDir(path)
	if err != nil {
		fmt.Println(err)
	}
	pathSep := string(os.PathSeparator)
	for _, file := range dir {
		if file.IsDir() {
			dirs = append(dirs, path+pathSep+file.Name())
			GetFiles(path+pathSep+file.Name(), tp)
		} else {
			OK := strings.HasSuffix(file.Name(), "."+tp)
			if OK {
				files = append(files, path+pathSep+file.Name())
			}
		}
	}
	for _, table := range dirs {
		temp, _ := GetFiles(table, tp)
		for _, temp1 := range temp {
			files = append(files, temp1)
		}
	}
	return files, err
}

func GetFileLineNum(path string) (int, error) {
	file, err2 := ioutil.ReadFile(path)
	if err2 != nil {
		fmt.Println(err2)
	}
	r := bytes.NewReader(file)

	var readSize int
	var err error
	var count int

	buf := make([]byte, 1024)

	for {
		readSize, err = r.Read(buf)
		if err != nil {
			break
		}

		var buffPosition int
		for {
			i := bytes.IndexByte(buf[buffPosition:], '\n')
			if i == -1 || readSize == buffPosition {
				break
			}
			buffPosition += i + 1
			count++
		}
	}
	if readSize > 0 && count == 0 || count > 0 {
		count++
	}
	if err == io.EOF {
		return count, nil
	}

	return count, err
}
